# -*- coding: utf-8 -*-
"""
@Time    : 2024/7/27 18:34 
@Author  : ZhangShenao 
@File    : 5.使用SemanticChunker语义相似性文档分割器.py 
@Desc    : 使用SemanticChunker语义相似性文档分割器

使用SemanticChunker,可以按照上下文语义,对文档进行分割
它底层通过Embedding向量的余弦相似度,来计算文档不同分块之间的相关性

核心原理:
1. 将文档按照正则表达式分割符进行分割
2. 根据传递的缓冲大小前后拼接字符串
3. 计算每个拼接后的新字符串的Embedding向量,然后计算这些文本的相似度
4. 根据传入的breakpoint类型和阈值,将相似度超过阈值的文本片段合并到一起,从而实现语义相似度分割

"""
import dotenv
from langchain_community.document_loaders import UnstructuredFileLoader
from langchain_community.embeddings import ZhipuAIEmbeddings
from langchain_experimental.text_splitter import SemanticChunker

# 加载环境变量
dotenv.load_dotenv()

# 创建Embedding模型
embeddings = ZhipuAIEmbeddings(model='embedding-2')

# 加载文档
loader = UnstructuredFileLoader('./docs/骆驼祥子.txt')
docs = loader.load()

# 创建语义文档分割器
splitter = SemanticChunker(
    embeddings=embeddings,  # 指定Embedding模型,SemanticChunker底层通过余弦相似度计算相似性
    sentence_split_regex=r'(?<=[。？！])',  # 指定语句分隔符正则表达式
    number_of_chunks=5,  # 指定最终的分块数量
    add_start_index=True,  # 添加起始索引
)

# 使用SemanticChunker分割文档
chunks = splitter.split_documents(docs)
for chunk in chunks:
    print(f'文档块大小: {len(chunk.page_content)}, 文档内容: {chunk.page_content}, 元数据: {chunk.metadata}')

text = '''祥子站在门口，看着脚下的土地，心里想着自己的车。他觉得自己好像是一个被遗弃的孩子，孤独而又无助。他的车，那辆曾经让他自豪的车，现在却成了他心中的痛。他不知道自己还能做什么，只能站在那里，任由心中的悲伤泛滥。

天气热的让人喘不过气来，祥子拉着车在街上慢慢地走着。他的衣服已经被汗水湿透，贴在身上，感觉异常难受。街上的行人很少，大家都躲进了阴凉的地方。祥子没有地方可去，只能在这烈日下继续他的劳作。

祥子有时候会想，自己的命运是不是早就注定了。他努力地工作，努力地生活，但总是感觉离幸福那么遥远。他看着那些有钱人，他们什么都不用做，就能享受到一切。而他，即使拼尽全力，也不过是别人眼中的一个小人物。

夜晚的北京城，安静而又神秘。祥子坐在自己的小屋里，听着外面的声音。他知道，这座城市里有太多和他一样的人，他们在黑暗中挣扎，寻找生活的出路。祥子有时候会想，如果有一天他能有自己的车，自己的生活会不会有所不同。

祥子看着刘四爷，那个曾经让他敬畏的人，现在在他眼里却变得那么渺小。他知道，刘四爷的财富和地位都是建立在别人的痛苦之上的。祥子不想成为这样的人，他只想堂堂正正地活着，哪怕生活再艰难。
'''
chunk = '祥子站在门口，看着脚下的土地，心里想着自己的车。 他觉得自己好像是一个被遗弃的孩子，孤独而又无助。'
print(text.find(chunk, 0))
